home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / SendText.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  10KB  |  604 lines

  1. /*
  2. **    SendText.c
  3. **
  4. **    Text sending support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* MatchPrompt():
  17.      *
  18.      *    Search incoming data stream for a match.
  19.      */
  20.  
  21. BOOL
  22. MatchPrompt(STRPTR Data,LONG Size,STRPTR Prompt,LONG PromptLen)
  23. {
  24.     STATIC LONG WaitCount,PromptCount;
  25.  
  26.     if(!Data)
  27.         WaitCount = PromptCount = 0;
  28.     else
  29.     {
  30.         UBYTE c,Mask;
  31.  
  32.         if(Config->SerialConfig->StripBit8)
  33.             Mask = 0x7F;
  34.         else
  35.             Mask = 0xFF;
  36.  
  37.         do
  38.         {
  39.             if(c = ((*Data++) & Mask))
  40.             {
  41.                 BOOL MatchMade;
  42.  
  43.                 do
  44.                 {
  45.                     MatchMade = FALSE;
  46.  
  47.                     if(PromptCount == WaitCount)
  48.                     {
  49.                         if(c == Prompt[WaitCount] & Mask)
  50.                         {
  51.                             MatchMade = TRUE;
  52.  
  53.                             if(PromptLen == ++PromptCount)
  54.                                 return(TRUE);
  55.                         }
  56.                     }
  57.  
  58.                     if(MatchMade)
  59.                         WaitCount++;
  60.                     else
  61.                     {
  62.                         if(WaitCount)
  63.                         {
  64.                             WaitCount = 0;
  65.  
  66.                             PromptCount = 0;
  67.                         }
  68.                         else
  69.                             break;
  70.                     }
  71.                 }
  72.                 while(!WaitCount);
  73.             }
  74.         }
  75.         while(--Size);
  76.     }
  77.  
  78.     return(FALSE);
  79. }
  80.  
  81.     /* LocalWaitForPrompt(STRPTR Prompt,LONG PromptLen):
  82.      *
  83.      *    Scan the incoming data flow for a certain string.
  84.      */
  85.  
  86. STATIC BOOL
  87. LocalWaitForPrompt(STRPTR Prompt,LONG PromptLen)
  88. {
  89.     ULONG Signals;
  90.     BOOL GotIt;
  91.  
  92.     MatchPrompt(NULL,0,NULL,0);
  93.  
  94.         /* Start the timer. */
  95.  
  96.     StartTime(Config->ClipConfig->SendTimeout / 100,(Config->ClipConfig->SendTimeout % 100) * 10000);
  97.  
  98.         /* Lock the current xOFF state and clear the xOFF flag. */
  99.  
  100.     Lock_xOFF();
  101.     Clear_xOFF();
  102.  
  103.     GotIt = FALSE;
  104.  
  105.         /* Loop until the prompt is found or the timer elapses. */
  106.  
  107.     do
  108.     {
  109.         Signals = (*SerialWaitForData)(SIG_TIMER);
  110.  
  111.         if(Signals & SIG_SERIAL)
  112.         {
  113.             ULONG Length;
  114.  
  115.                 /* Check how much data is available. */
  116.  
  117.             if(Length = (*SerialGetWaiting)())
  118.             {
  119.                     /* Don't read more than the buffer will hold. */
  120.  
  121.                 if(Length > SerialBufferSize / 2)
  122.                     Length = SerialBufferSize / 2;
  123.  
  124.                     /* Read the data. */
  125.  
  126.                 if(Length = (*SerialRead)(ReadBuffer,Length))
  127.                 {
  128.                         /* Got some more data. */
  129.  
  130.                     BytesIn += Length;
  131.  
  132.                         /* Translate the buffer contents if necessary. */
  133.  
  134.                     if(Translate_CR_LF)
  135.                         Length = (*Translate_CR_LF)(ReadBuffer,Length);
  136.                     else
  137.                         Length = 1;
  138.  
  139.                     if(Length)
  140.                     {
  141.                         ConProcess(ReadBuffer,Length);
  142.  
  143.                             /* Check if this is it. */
  144.  
  145.                         if(MatchPrompt(ReadBuffer,Length,Prompt,PromptLen))
  146.                             GotIt = TRUE;
  147.                     }
  148.                 }
  149.             }
  150.         }
  151.  
  152.             /* Stop when the bell rings. */
  153.  
  154.         if(Signals & SIG_TIMER)
  155.             break;
  156.     }
  157.     while(!GotIt);
  158.  
  159.         /* Stop the timer. */
  160.  
  161.     StopTime();
  162.  
  163.     Unlock_xOFF();
  164.  
  165.     return(GotIt);
  166. }
  167.  
  168.     /* SendLinePrompt(STRPTR Line,LONG Len):
  169.      *
  170.      *    Send text line, wait for prompt.
  171.      */
  172.  
  173. BOOL
  174. SendLinePrompt(STRPTR Line,LONG Len)
  175. {
  176.     LONG i;
  177.  
  178.     if(Len == -1)
  179.         Len = strlen(Line);
  180.  
  181.     while(Len)
  182.     {
  183.         i = 0;
  184.  
  185.         while(i < Len && Line[i] != '\r')
  186.             i++;
  187.  
  188.         if(Line[i] == '\r')
  189.         {
  190.             i++;
  191.  
  192.             SerWrite(Line,i);
  193.  
  194.             if(!LocalWaitForPrompt(SendPrompt,SendPromptLen))
  195.                 return(FALSE);
  196.         }
  197.         else
  198.         {
  199.             if(i)
  200.                 SerWrite(Line,i);
  201.         }
  202.  
  203.         Len        -= i;
  204.         Line    += i;
  205.     }
  206.  
  207.     return(TRUE);
  208. }
  209.  
  210.     /* SendLineSimple(STRPTR Line,LONG Len):
  211.      *
  212.      *    Send a text line, no fancy features.
  213.      */
  214.  
  215. BOOL
  216. SendLineSimple(STRPTR Line,LONG Len)
  217. {
  218.     if(Len == -1)
  219.         Len = strlen(Line);
  220.  
  221.     SerWrite(Line,Len);
  222.  
  223.     return(TRUE);
  224. }
  225.  
  226.     /* SendLineDial(STRPTR Line,LONG Len):
  227.      *
  228.      *    The SendLineSimple for the dialer and init commands.
  229.      */
  230.  
  231. BOOL
  232. SendLineDial(STRPTR Line,LONG Len)
  233. {
  234.     if(Len == -1)
  235.         Len = strlen(Line);
  236.  
  237.     if(Config->ModemConfig->CharSendDelay > 0)
  238.     {
  239.         ULONG    Seconds    = Config->ModemConfig->CharSendDelay / MILLION,
  240.                 Micros    = Config->ModemConfig->CharSendDelay % MILLION;
  241.  
  242.         while(Len--)
  243.         {
  244.             SerWrite(Line++,1);
  245.  
  246.             DelayTime(Seconds,Micros);
  247.         }
  248.     }
  249.     else
  250.         SerWrite(Line,Len);
  251.  
  252.     return(TRUE);
  253. }
  254.  
  255.     /* SendLineDelay(STRPTR Line,LONG Len):
  256.      *
  257.      *    Send a text line, include a delay where necessary.
  258.      */
  259.  
  260. BOOL
  261. SendLineDelay(STRPTR Line,LONG Len)
  262. {
  263.     if(Len == -1)
  264.         Len = strlen(Line);
  265.  
  266.     while(Len--)
  267.     {
  268.         SerWrite(Line,1);
  269.  
  270.         if(*Line == '\r')
  271.             DelayTime(Config->ClipConfig->LineDelay / 100,(Config->ClipConfig->LineDelay % 100) * 10000);
  272.         else
  273.             DelayTime(Config->ClipConfig->CharDelay / 100,(Config->ClipConfig->CharDelay % 100) * 10000);
  274.  
  275.         Line++;
  276.     }
  277.  
  278.     return(TRUE);
  279. }
  280.  
  281.     /* SendLineEcho(STRPTR Line,LONG Len):
  282.      *
  283.      *    Send a text line, wait for single characters to be echoed.
  284.      */
  285.  
  286. BOOL
  287. SendLineEcho(STRPTR Line,LONG Len)
  288. {
  289.     ULONG Signals;
  290.     BOOL GotIt;
  291.  
  292.     if(Len == -1)
  293.         Len = strlen(Line);
  294.  
  295.         /* Lock the current xOFF state and clear the xOFF flag. */
  296.  
  297.     Lock_xOFF();
  298.     Clear_xOFF();
  299.  
  300.     while(Len--)
  301.     {
  302.             /* Send the next character. */
  303.  
  304.         SerWrite(Line,1);
  305.  
  306.             /* Start the timer. */
  307.  
  308.         StartTime(Config->ClipConfig->SendTimeout / 100,(Config->ClipConfig->SendTimeout % 100) * 10000);
  309.  
  310.             /* Loop until we got the character we wanted or the time elapses. */
  311.  
  312.         GotIt = FALSE;
  313.  
  314.         do
  315.         {
  316.             Signals = (*SerialWaitForData)(SIG_TIMER);
  317.  
  318.                 /* Did we receive new data? */
  319.  
  320.             if(Signals & SIG_SERIAL)
  321.             {
  322.                     /* Is there any character waiting? */
  323.  
  324.                 if((*SerialGetWaiting)())
  325.                 {
  326.                         /* Read that character. */
  327.  
  328.                     if((*SerialRead)(ReadBuffer,1))
  329.                     {
  330.                         ULONG Length;
  331.  
  332.                         BytesIn++;
  333.  
  334.                             /* Check if the character needs translation. */
  335.  
  336.                         if(Translate_CR_LF)
  337.                             Length = (*Translate_CR_LF)(ReadBuffer,1);
  338.                         else
  339.                             Length = 1;
  340.  
  341.                         if(Length)
  342.                             ConProcess(ReadBuffer,Length);
  343.  
  344.                             /* Is that it? */
  345.  
  346.                         if(Length == 1 && ReadBuffer[0] == Line[0])
  347.                             GotIt = TRUE;
  348.                     }
  349.                 }
  350.             }
  351.  
  352.                 /* Did the bell ring? */
  353.  
  354.             if(Signals & SIG_TIMER)
  355.                 break;
  356.         }
  357.         while(!GotIt);
  358.  
  359.             /* Stop the timer. */
  360.  
  361.         StopTime();
  362.  
  363.             /* Check if we got the echo. If not, return an error. */
  364.  
  365.         if(!GotIt)
  366.         {
  367.             Unlock_xOFF();
  368.             return(FALSE);
  369.         }
  370.  
  371.         Line++;
  372.     }
  373.  
  374.     Unlock_xOFF();
  375.  
  376.     return(TRUE);
  377. }
  378.  
  379.     /* SendLineAnyEcho(STRPTR Line,LONG Len):
  380.      *
  381.      *    Send a text line, wait for characters to be echoed.
  382.      */
  383.  
  384. BOOL
  385. SendLineAnyEcho(STRPTR Line,LONG Len)
  386. {
  387.     ULONG Signals;
  388.     BOOL GotIt;
  389.  
  390.     if(Len == -1)
  391.         Len = strlen(Line);
  392.  
  393.         /* Lock the current xOFF state and clear the xOFF flag. */
  394.  
  395.     Lock_xOFF();
  396.     Clear_xOFF();
  397.  
  398.     while(Len--)
  399.     {
  400.             /* Send the next character. */
  401.  
  402.         SerWrite(Line,1);
  403.  
  404.             /* Start the timer. */
  405.  
  406.         StartTime(Config->ClipConfig->SendTimeout / 100,(Config->ClipConfig->SendTimeout % 100) * 10000);
  407.  
  408.             /* Loop until we got the character we wanted or the time elapses. */
  409.  
  410.         GotIt = FALSE;
  411.  
  412.         do
  413.         {
  414.             Signals = (*SerialWaitForData)(SIG_TIMER);
  415.  
  416.                 /* Did we receive new data? */
  417.  
  418.             if(Signals & SIG_SERIAL)
  419.             {
  420.                     /* Is there any character waiting? */
  421.  
  422.                 if((*SerialGetWaiting)())
  423.                 {
  424.                         /* Read that character. */
  425.  
  426.                     if((*SerialRead)(ReadBuffer,1))
  427.                     {
  428.                         LONG Length;
  429.  
  430.                         BytesIn++;
  431.  
  432.                         if(Translate_CR_LF)
  433.                             Length = (*Translate_CR_LF)(ReadBuffer,1);
  434.                         else
  435.                             Length = 1;
  436.  
  437.                         if(Length)
  438.                             ConProcess(ReadBuffer,Length);
  439.  
  440.                         GotIt = TRUE;
  441.                     }
  442.                 }
  443.             }
  444.  
  445.                 /* Did the bell ring? */
  446.  
  447.             if(Signals & SIG_TIMER)
  448.                 break;
  449.         }
  450.         while(!GotIt);
  451.  
  452.             /* Stop the timer. */
  453.  
  454.         StopTime();
  455.  
  456.             /* Check if we got the echo. If not, return an error. */
  457.  
  458.         if(!GotIt)
  459.         {
  460.             Unlock_xOFF();
  461.             return(FALSE);
  462.         }
  463.  
  464.         Line++;
  465.     }
  466.  
  467.     Unlock_xOFF();
  468.  
  469.     return(TRUE);
  470. }
  471.  
  472.     /* SendLineKeyDelay(STRPTR Line,LONG Len):
  473.      *
  474.      *    Send a text line, include keyboard delay pauses between characters.
  475.      */
  476.  
  477. BOOL
  478. SendLineKeyDelay(STRPTR Line,LONG Len)
  479. {
  480.     struct Preferences Prefs;
  481.  
  482.     if(Len == -1)
  483.         Len = strlen(Line);
  484.  
  485.         /* Get current key repeat delay. */
  486.  
  487.     GetPrefs(&Prefs,offsetof(struct Preferences,KeyRptDelay));
  488.  
  489.         /* Any delay specified at all? */
  490.  
  491.     if(Prefs.KeyRptSpeed.tv_secs || Prefs.KeyRptSpeed.tv_micro)
  492.     {
  493.         while(Len--)
  494.         {
  495.             SerWrite(Line++,1);
  496.  
  497.             if(Len)
  498.                 DelayTime(Prefs.KeyRptSpeed.tv_secs,Prefs.KeyRptSpeed.tv_micro);
  499.         }
  500.     }
  501.     else
  502.         SerWrite(Line,Len);
  503.  
  504.     return(TRUE);
  505. }
  506.  
  507.     /* ChangeSendLine(SENDLINE NewSendLine):
  508.      *
  509.      *    Change the routine that sends full lines of text.
  510.      */
  511.  
  512. SENDLINE
  513. ChangeSendLine(SENDLINE NewSendLine)
  514. {
  515.     SENDLINE OldSendLine;
  516.  
  517.     OldSendLine    = SendLine;
  518.     SendLine    = NewSendLine;
  519.  
  520.     return(OldSendLine);
  521. }
  522.  
  523.     /* RestoreSendLine():
  524.      *
  525.      *    Restore the SendLine pointer to its original routine.
  526.      */
  527.  
  528. VOID
  529. RestoreSendLine(SENDLINE ChangedSendLine,SENDLINE OriginalSendLine)
  530. {
  531.     if(SendLine == ChangedSendLine)
  532.         SendLine = OriginalSendLine;
  533. }
  534.  
  535.     /* SendSetup():
  536.      *
  537.      *    Choose the right routine for the text line output job.
  538.      */
  539.  
  540. VOID
  541. SendSetup()
  542. {
  543.         /* Prepare the prompt string. */
  544.  
  545.     if(Config->ClipConfig->LinePrompt[0])
  546.         SendPromptLen = TranslateString(Config->ClipConfig->LinePrompt,SendPrompt);
  547.     else
  548.     {
  549.         SendPrompt[0] = 0;
  550.         SendPromptLen = 0;
  551.     }
  552.  
  553.         /* Pick the line send routine. */
  554.  
  555.     switch(Config->ClipConfig->PacingMode)
  556.     {
  557.         case PACE_DIRECT:
  558.  
  559.             SendLine = (SENDLINE)SendLineSimple;
  560.             break;
  561.  
  562.         case PACE_ECHO:
  563.  
  564.             if(Config->ClipConfig->SendTimeout)
  565.                 SendLine = (SENDLINE)SendLineEcho;
  566.             else
  567.                 SendLine = (SENDLINE)SendLineSimple;
  568.  
  569.             break;
  570.  
  571.         case PACE_ANYECHO:
  572.  
  573.             if(Config->ClipConfig->SendTimeout)
  574.                 SendLine = (SENDLINE)SendLineAnyEcho;
  575.             else
  576.                 SendLine = (SENDLINE)SendLineSimple;
  577.  
  578.             break;
  579.  
  580.         case PACE_PROMPT:
  581.  
  582.             if(Config->ClipConfig->SendTimeout)
  583.                 SendLine = (SENDLINE)SendLinePrompt;
  584.             else
  585.                 SendLine = (SENDLINE)SendLineSimple;
  586.  
  587.             break;
  588.  
  589.         case PACE_DELAY:
  590.  
  591.             if(Config->ClipConfig->LineDelay || Config->ClipConfig->CharDelay)
  592.                 SendLine = (SENDLINE)SendLineDelay;
  593.             else
  594.                 SendLine = (SENDLINE)SendLineSimple;
  595.  
  596.             break;
  597.  
  598.         case PACE_KEYBOARD:
  599.  
  600.             SendLine = (SENDLINE)SendLineKeyDelay;
  601.             break;
  602.     }
  603. }
  604.